<template>
  <h3>
    出现没有删干净,请查看是否是子级目录并未创建,本应用根据epub的目录做映射合并.
  </h3>
   <section class="action">
      <a-select
          v-model:value="finialLevel"
          style="width: 160px;margin-left:25px"
          :options="PressOptions"
      ></a-select>
     <a-button type="primary"   style="margin:0 25px " :icon="h(ChromeOutlined )" @click="handleExport">导出</a-button>
    </section>
  <a-spin :spinning="spinning">
    <a-directory-tree
        v-model:expandedKeys="expandedKeys"
        v-model:selectedKeys="selectedKeys"
        :fieldNames="fieldNames"
        multiple
        :tree-data="navigation"
    >
      <template #title="{ dataRef }">
        <a-tooltip placement="topLeft">
          <template #title>
            <span>{{dataRef.href}}</span>
          </template>
        <span >{{ dataRef.label }} 层级 : {{dataRef.level}}</span>
        </a-tooltip>
      </template>

    </a-directory-tree>
  </a-spin>

</template>
<script setup>
import JsonData from './loadURL.json'
import {ChromeOutlined, EditOutlined, ZoomInOutlined} from '@ant-design/icons-vue';
import {getCurrentInstance, h, reactive, ref, unref} from "vue";
import JSZip from "jszip";
import ePub from "epubjs";
import {message} from "ant-design-vue";
import _ from "lodash";
const expandedKeys = ref();
const selectedKeys = ref();
//@ts-ignore
let {ctx: that, proxy} = getCurrentInstance()
let  spinning = ref(true)
let zipUtil = reactive({})
let  htmlData =  reactive({})

let  startLine =ref(false)

const props = defineProps(['file'])
let  preview =  ref(false)
let  metadata =reactive({})
let  fieldNames = reactive({
  children:'subitems', title:'label', key:'id'
});
let  navigation = ref([])

let  files =ref([])

let  finialLevel =ref(1)

let  PressOptions = ref([])
//函数
let  loadBook = ()=>{
  // 读取文件为ArrayBuffer
  const reader = new FileReader();
  reader.readAsArrayBuffer(props.file);
  reader.onload =  async (e) => {
    // //处理书籍
    const book = ePub(e.target.result);
    book.loaded.navigation.then(res=>{
      console.log(book, 'book')
      let  data =  JSON.parse(JSON.stringify(res.toc))
      let  finial = [];
      data.forEach(item=>{
        item.level = 1
      })
      let  stack = [...data]
      let  max  = 1;
      while (stack.length>0){
        let first = stack.shift();
        finial.push(first)
        if (Array.isArray(first.subitems)){
          let newVar = first.level +1;
          if (max<newVar ){
            max =   newVar
          }
          first.subitems.forEach(item=>{
            item.level = newVar
          })
          stack.unshift(...first.subitems)
        }
      }
      navigation.value.splice(0)
      navigation.value.push(...data);
      spinning.value = false
      finial =  finial.map(item=>({
        label:item.label,
        href: book.path.directory +   item.href.replace(/(\.xhtml|\.html|\.htm).*$/, '$1'),
        level:item.level
      }))
      for (let i = 0; i <=max; i++) {
        PressOptions.value.push({
          value: i,
          label: i,
        })
      }
      files.value = finial
    })
    book.loaded.metadata.then( async book => {
      metadata = book
      // 加载EPUB文件
      let  zip =  await JSZip.loadAsync(reader.result);
      zipUtil  =zip;
      let  tempList =[]
      for (const [relativePath, zipEntry] of Object.entries(zip.files)) {
        // 判断文件是否是.xhtml或.html文件

        if (zipEntry.name.endsWith(".xhtml") || zipEntry.name.endsWith(".html") || zipEntry.name.endsWith(".htm")) {
          // 获取文本文件的内容
          try {
            const content = await zipEntry.async("string");
            // 加载HTML文档
            let item = {
              title: zipEntry.name,
              content: content
            }
            tempList.push(item)
          }catch(err){
            console.log(err, 'err')
          }
        }
      }
      if (tempList[0].title.startsWith("/")){
        startLine.value = true;
      }
      tempList.forEach(item=>{
        htmlData[item.title]  = item.content
      })
      message.success("文件解析成功!")

    })
  };
}
//主进程
let  main =()=>{
  loadBook();
}
main();


let    getDom  =(docListElement)=>{
  let dom = null
  const parser = new DOMParser()
  const isXHTML = docListElement.href.includes('.xhtml')|| docListElement.content.includes('http://www.w3.org/1999/xhtml')
  if (isXHTML) {
    dom = parser.parseFromString(docListElement.content, 'application/xhtml+xml')
  } else {
    dom = parser.parseFromString(docListElement.content, 'text/html')
  }
  return dom;
}

let  generateEpub =(allFiles)=>{

  let  removeFiles = []
  for (const key in allFiles) {
    let oneChapter = allFiles[key];
    let  chapterDOM = null;
    oneChapter.forEach((item,index)=>{
      let htmlDatum = htmlData[item.href];
      item.content  =  htmlDatum;
      let dom = getDom(item);
      let body = dom.documentElement.querySelector("body");
      if (index === 0){
        chapterDOM = dom
      }
      if (index>0){
        let mainBody = chapterDOM.documentElement.querySelector("body");
        mainBody.innerHTML +=  body.innerHTML;
      }
    })
    let map = oneChapter.slice(1).map(item=>item.href);
    removeFiles.push(...map);
    //@ts-ignore
    zipUtil.file(oneChapter[0].href, chapterDOM.documentElement.outerHTML);
  }
  console.log(removeFiles, 'removeFiles')
  removeFiles.forEach(item=>{
    zipUtil.remove(item);
  })


  //@ts-ignore
  zipUtil.generateAsync({ type: 'blob' }).then((updatedEpubBlob)=> {
    // 下载修改后的 EPUB 文件
    let downloadLink = document.createElement('a');
    downloadLink.href = window.URL.createObjectURL(updatedEpubBlob);
    downloadLink.download = metadata.title+'.epub';
    downloadLink.click();
    message.success("保存成功!")
  });
}

let  handleExport = ()=>{
  console.log(htmlData, 'htmlData')
  let  allFiles ={}
  let  currentChapter = null

  //删除前缀
  let href = files.value[0].href;
  if (!startLine.value){
    if (href.startsWith("/")){
      files.value.forEach(item=>{
        item.href = item.href.replace(/^\/+/,'')
      })
    }
  }

if (finialLevel.value === 0){
  allFiles[metadata.title] = files.value
}else{
    files.value.forEach(item=>{
      let value = unref(finialLevel.value);
      if ( value === item.level){
        currentChapter =   item.label
        allFiles[currentChapter] = [item]
      }else if(value  < item.level){
        allFiles[currentChapter].push(item)
      }else if(value > item.level){
        currentChapter = null
      }
    })
  }
  for (const key in allFiles) {
    allFiles[key] =  _.uniqWith(allFiles[key] ,(a, b) => a.href === b.href);
  }
  console.log(allFiles, 'allFiles')
  
  let strings = Object.keys(allFiles);
  console.log(strings.length, 'strings.length')
  generateEpub(allFiles)

}
</script>
<style scoped >
/* For demo */
:deep(.slick-dots) {
  position: relative;
  height: auto;
}
:deep(.slick-slide img) {
  border: 5px solid #fff;
  display: block;
  margin: auto;
  max-width: 80%;
}
:deep(.slick-arrow) {
  display: none !important;
}
:deep(.slick-thumb) {
  bottom: 0px;
}
:deep(.slick-thumb li) {
  width: 60px;
  height: 45px;
}
:deep(.slick-thumb li img) {
  width: 100%;
  height: 100%;
  filter: grayscale(100%);
  display: block;
}
:deep .slick-thumb li.slick-active img {
  filter: grayscale(0%);
}

:deep .ant-tabs{
  max-height:calc(100vh - 420px) ;

}


.action{
  display: flex;
  text-align: left;
}
.fixed{
  flex:1
}
.countNumber{
  color: #ff0623;
}
main{
  display: flex;
  margin-top: 20px;
  height: calc(100vh - 120px);

}
.nav{
  width: 180px;
  overflow-y: scroll;
  user-select: none;
}
.title{
  padding: 10px 5px ;
  border-left: 1px solid  #4096ff;
  border-bottom: 1px solid  #4096ff;
  cursor: pointer;
}

.title:first-child{
  border-top: 1px solid  #4096ff;
}

.select{
  background: #4096ff;
  color: white;

}

.tableList {
  overflow-y: scroll;
  width: 640px;
}

.html_content{
  overflow-y: scroll;
  border-right: 1px solid  #4096ff;
  border-left: 1px solid  #4096ff;
  border-bottom: 1px solid  #4096ff;
  border-top: 1px solid  #4096ff;
  flex: 1;
  padding: 20px;
}


.table_wrapper {
  border: 1px  dashed #1677ff ;
  margin-top: 10px ;
  border-radius: 15px;
  padding: 10px;
}


.table_operate{
  padding: 10px;

  border-radius: 15px;

}

</style>
